package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.app.domain.vo.AppSalesLevelVo;
import com.ruoyi.app.domain.vo.AppUserVo;
import com.ruoyi.app.service.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.BillType;
import com.ruoyi.common.enums.CoinType;
import com.ruoyi.common.enums.DetailEnums;
import com.ruoyi.common.utils.OrderNumUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.system.service.ISysConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.app.domain.bo.AppSalesOrderBo;
import com.ruoyi.app.domain.vo.AppSalesOrderVo;
import com.ruoyi.app.domain.AppSalesOrder;
import com.ruoyi.app.mapper.AppSalesOrderMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 充值订单Service业务层处理
 *
 * @author heise
 * @date 2025-06-28
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class AppSalesOrderServiceImpl implements IAppSalesOrderService {

    private final AppSalesOrderMapper baseMapper;
    private final IAppUserService appUserService;
    private final IAppAssetService appAssetService;
    private final IAppDetailService appDetailService;
    private final ISysConfigService sysConfigService;
    private final IAppSalesLevelService appSalesLevelService;

    /**
     * 查询充值订单
     */
    @Override
    public AppSalesOrderVo queryById(Long salesOrderId) {
        return baseMapper.selectVoById(salesOrderId);
    }

    @Override
    public AppSalesOrderVo queryOrderNo(String orderNo) {
        LambdaQueryWrapper<AppSalesOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AppSalesOrder::getOrderNo, orderNo);
        return baseMapper.selectVoOne(wrapper);
    }

    /**
     * 查询充值订单列表
     */
    @Override
    public TableDataInfo<AppSalesOrderVo> queryPageList(AppSalesOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppSalesOrder> lqw = buildQueryWrapper(bo);
        Page<AppSalesOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询充值订单列表
     */
    @Override
    public List<AppSalesOrderVo> queryList(AppSalesOrderBo bo) {
        LambdaQueryWrapper<AppSalesOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 完成订单成功
     *
     * @param salesOrderVo 订单信息
     * @param tradeNo      订单号
     * @param payType      支付方式
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void downOrder(AppSalesOrderVo salesOrderVo, String tradeNo, String payType) {
        AppSalesOrderBo salesOrderBo = new AppSalesOrderBo();
        salesOrderBo.setPayType(payType);
        salesOrderBo.setStatus(Constants.FAIL);
        salesOrderBo.setTransactionOrderNo(tradeNo);
        salesOrderBo.setSalesOrderId(salesOrderVo.getSalesOrderId());
        if (updateByBo(salesOrderBo)) {
            AppUserVo userVo = appUserService.queryById(salesOrderVo.getUserId());
            userVo.setSalesLevel(2L);
            appUserService.updateByVo(userVo);
            sendSalesLevelReward(userVo.getParentId());
            updateSalesLevel(userVo.getParentId());
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void sendSalesLevelReward(Long userId) {
        String isOpen = sysConfigService.selectConfigByKey("app.salesLevel.reward");
        if (StringUtils.equals(Constants.FAIL, isOpen) && userId != null) {
            String remark = "直推充值奖励";
            AppUserVo userVo = appUserService.queryById(userId);
            AppSalesLevelVo levelVo = appSalesLevelService.queryById(userVo.getSalesLevel());
            BigDecimal balance = levelVo.getRewardOne();
            BigDecimal integral = balance.multiply(levelVo.getRewardTwo()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            if (balance.compareTo(BigDecimal.ZERO) > 0) {
                appAssetService.addBalance(userId, balance);
                appAssetService.addIntegral(userId, integral);
                appDetailService.insert(userVo.getId(), balance, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.GOLD.getCode(), DetailEnums.RECHARGE_REWARD.getCode(), remark, null);
                appDetailService.insert(userVo.getId(), integral, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.INTE.getCode(), DetailEnums.RECHARGE_REWARD.getCode(), remark, null);
            }
            AppUserVo ppUserVo = appUserService.queryById(userVo.getParentId());
            if (userVo.getParentId() != null && ppUserVo.getSalesLevel() > userVo.getSalesLevel()) {
                BigDecimal erBalance = BigDecimal.ZERO;
                BigDecimal erIntegral = BigDecimal.ZERO;
                String erRemark = "间推充值奖励";
                AppSalesLevelVo ppLevelVo = appSalesLevelService.queryById(userVo.getSalesLevel());
                if (userVo.getSalesLevel().equals(3L)) {
                    erBalance = new BigDecimal("98");
                    erIntegral = erBalance.multiply(ppLevelVo.getRewardTwo()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
                } else if (userVo.getSalesLevel().equals(4L)) {
                    erBalance = new BigDecimal("298");
                    erIntegral = erBalance.multiply(ppLevelVo.getRewardTwo()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
                } else if (userVo.getSalesLevel().equals(5L)) {
                    erBalance = new BigDecimal("498");
                    erIntegral = erBalance.multiply(ppLevelVo.getRewardTwo()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
                }
                if (erBalance.compareTo(BigDecimal.ZERO) > 0) {
                    appAssetService.addBalance(userVo.getParentId(), balance);
                    appAssetService.addIntegral(userVo.getParentId(), integral);
                    appDetailService.insert(userVo.getParentId(), erBalance, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.GOLD.getCode(), DetailEnums.RECHARGE_REWARD.getCode(), erRemark, userVo.getId());
                    appDetailService.insert(userVo.getParentId(), erIntegral, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.INTE.getCode(), DetailEnums.RECHARGE_REWARD.getCode(), erRemark, userVo.getId());
                }
            }
        }
    }


    /**
     * 更新用户等级
     *
     * @param id 用户id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateSalesLevel(Long id) {
        if (id == null) {
            return false;
        }
        List<Long> allParentIds = appUserService.findAllParentIds(id);
        allParentIds.add(id);
        allParentIds.sort(Comparator.reverseOrder());
        log.info("用户充值所有上级id：{}", allParentIds);
        for (Long userId : allParentIds) {
            AppUserVo userVo = appUserService.queryById(userId);
            if (userVo.getSalesLevel() >= 5) {
                return false;
            }
            long nextLevel = userVo.getSalesLevel() + 1;
            int sign = 0;
            List<AppUserVo> zhiTui = appUserService.zhituiList(userVo.getId());
            List<AppUserVo> jianTui = appUserService.jiantuiList(userVo.getId());
            if (nextLevel == 3) {
                long zhiTuiCount = zhiTui.stream().filter(e -> e.getSalesLevel().equals(2L)).map(AppUserVo::getSalesLevel).count();
                long jianTuiCount = jianTui.stream().filter(e -> e.getSalesLevel().equals(2L)).map(AppUserVo::getSalesLevel).count();
                if (zhiTuiCount > 3 && jianTuiCount > 7) {
                    sign = 1;
                }
            } else if (nextLevel == 4) {
                long threeUser = zhiTui.stream().map(e -> e.getSalesLevel().equals(3L)).count();
                if (threeUser >= 5) {
                    long zhiTuiCount = zhiTui.stream().filter(e -> e.getSalesLevel().equals(2L)).map(AppUserVo::getSalesLevel).count();
                    long jianTuiCount = jianTui.stream().filter(e -> e.getSalesLevel().equals(2L)).map(AppUserVo::getSalesLevel).count();
                    if (zhiTuiCount + jianTuiCount >= 10) {
                        sign = 1;
                    }
                }
            } else if (nextLevel == 5) {
                long fourUser = zhiTui.stream().map(e -> e.getSalesLevel().equals(4L)).count();
                if (fourUser >= 3) {
                    long jianTuiCount = jianTui.stream().filter(e -> e.getSalesLevel().equals(4L)).map(AppUserVo::getSalesLevel).count();
                    if (fourUser + jianTuiCount >= 12) {
                        sign = 1;
                    }
                }
            }
            if (sign == 1) {
                userVo.setSalesLevel(nextLevel);
                appUserService.updateByVo(userVo);
            }
        }
        return true;
    }

    private LambdaQueryWrapper<AppSalesOrder> buildQueryWrapper(AppSalesOrderBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppSalesOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, AppSalesOrder::getUserId, bo.getUserId());
        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), AppSalesOrder::getOrderNo, bo.getOrderNo());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), AppSalesOrder::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getPayType()), AppSalesOrder::getPayType, bo.getPayType());
        return lqw;
    }

    /**
     * 新增充值订单
     */
    @Override
    public Boolean insertByBo(AppSalesOrderBo bo) {
        AppSalesOrder add = BeanUtil.toBean(bo, AppSalesOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setSalesOrderId(add.getSalesOrderId());
        }
        return flag;
    }

    /**
     * 修改充值订单
     */
    @Override
    public Boolean updateByBo(AppSalesOrderBo bo) {
        AppSalesOrder update = BeanUtil.toBean(bo, AppSalesOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppSalesOrder entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除充值订单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppSalesOrderBo create(AppSalesOrderBo bo) {
        String orderNo = OrderNumUtils.getInstance().generateOrderNo();
        bo.setOrderNo(orderNo);
        bo.setStatus(Constants.SUCCESS);
        bo.setOrderNumber(bo.getOrderPrice());
        return insertByBo(bo) ? bo : null;
    }
}
